//
//  DMBaseAPIManager.h
//  DaMaoMall
//
//  Created by HXHL-wally on 16/8/2.
//  Copyright © 2016年 daMao-wally. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "DMResponseModel.h"

@class DMBaseAPIManager;
extern NSString * const kDMAPIBaseManagerRequestId;

// For transfer data
@protocol DMAPIManagerDataReformer <NSObject>
@required
- (id)apiManager:(DMBaseAPIManager *)manager reformData:(NSDictionary *)data;

@end


typedef NS_ENUM (NSUInteger, DMRequestType){
    DMRequestTypeGet,
    DMRequestTypePost,
};

typedef NS_ENUM (NSInteger, DMAPIManagerResponseStatus){
    DMAPIManagerResponseStatusDefault = -1,             //没有产生过API请求，默认状态。
    DMAPIManagerResponseStatusTimeout = 101,            //请求超时
    DMAPIManagerResponseStatusNoNetwork = 102,          //网络不通
    DMAPIManagerResponseStatusSuccess = 200,            //API请求成功且返回数据正确
    DMAPIManagerResponseStatusParsingError = 201,       //API请求成功但返回数据不正确
    DMAPIManagerResponseStatusNeedLogin = 300,          //认证信息无效
    DMAPIManagerResponseStatusRequestError = 400,       //请求出错，参数或方法错误
    DMAPIManagerResponseStatusTypeServerCrash = 500,    //服务器出错
    DMAPIManagerResponseStatusTypeServerMessage = 600,  //服务器自定义消息
};


@protocol DMAPIManager <NSObject>

@required
- (NSString *)path;
- (NSString *)apiVersion;
- (BOOL)isAuth;

@optional
- (DMRequestType)requestType;
- (BOOL)isResponseJSONable;
- (BOOL)isRequestUsingJSON;

@end


@protocol DMAPIManagerDataSource <NSObject>
@required
- (NSDictionary *)paramsForAPI:(DMBaseAPIManager *)manager;
@end


@protocol DMAPIManagerDelegate <NSObject>
@required
- (void)apiManagerLoadDataSuccess:(DMBaseAPIManager *)manager;
- (void)apiManagerLoadDataFail:(DMResponseError *)error;
@end


@protocol DMAPIManagerInterceptor <NSObject>
@optional
- (BOOL)apiManager:(DMBaseAPIManager *)manager beforePerformSuccessWithResponseModel:(DMResponseModel *)responsemodel;
- (void)apiManager:(DMBaseAPIManager *)manager afterPerformSuccessWithResponseModel:(DMResponseModel *)responseModel;

- (BOOL)apiManager:(DMBaseAPIManager *)manager beforePerformFailWithResponseModel:(DMResponseError *)responseModel;
- (void)apiManager:(DMBaseAPIManager *)manager afterPerformFailWithResponseModel:(DMResponseError *)responseModel;

- (BOOL)apiManager:(DMBaseAPIManager *)manager shouldLoadRequestWithParams:(NSDictionary *)params;
- (void)apiManager:(DMBaseAPIManager *)manager afterLoadRequestWithParams:(NSDictionary *)params;
@end


@interface DMBaseAPIManager : NSObject

@property (nonatomic, assign, readonly) BOOL isLoading;

@property (nonatomic, weak) id<DMAPIManagerDataSource> dataSource;
@property (nonatomic, weak) id<DMAPIManagerDelegate> delegate;
@property (nonatomic, weak) id<DMAPIManagerInterceptor> interceptor;

- (NSInteger)loadData;
- (void)cancelAllRequests;
- (void)cancelRequestWithRequestId:(NSInteger)requestID;

- (BOOL)isReachable;

- (id)fetchData;
- (id)fetchDataWithReformer:(id<DMAPIManagerDataReformer>)reformer;
- (id)fetchDataFromModel; // 默认没有实现，需要覆盖

- (NSDictionary *)reformParams:(NSDictionary *)params;

// default
- (NSString *)host;
- (DMRequestType)requestType;   //default is DMRequestTypePost;
- (BOOL)isResponseJSONable;     //default is YES;
- (BOOL)isRequestUsingJSON;     //default is YES;


#pragma mark - 拦截器
// 用于子类需要监听相关事件，覆盖时需调用super对应方法
- (BOOL)beforePerformSuccessWithResponseModel:(DMResponseModel *)responseModel;
- (void)afterPerformSuccessWithResponseModel:(DMResponseModel *)responseModel;

- (BOOL)beforePerformFailWithResponseModel:(DMResponseError *)responseModel;
- (void)afterPerformFailWithResponseModel:(DMResponseError *)responseModel;

- (BOOL)shouldLoadRequestWithParams:(NSDictionary *)params;
- (void)afterLoadRequestWithParams:(NSDictionary *)params;

#pragma mark - 校验
// 需要校验则重写此方法
- (BOOL)isResponseDataCorrect:(DMResponseModel *)reponseModel;

@end
